package com.yonyougov.devops.cruxcisupport.aop;

import com.yonyougov.devops.cruxcisupport.component.PermissionCheck;
import com.yonyougov.devops.cruxcisupport.component.UserStore;
import com.yonyougov.devops.cruxcisupport.support.menu.ButtonPermission;
import com.yonyougov.devops.fwc.core.exception.BusinessException;
import lombok.extern.slf4j.Slf4j;
import org.aopalliance.aop.Advice;
import org.springframework.aop.*;
import org.springframework.aop.support.annotation.AnnotationMethodMatcher;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RestController;

import java.math.BigInteger;

@Component
@Slf4j
public class ButtonPermissionAop implements PointcutAdvisor {
    private final UserStore userStore;
    private final PermissionCheck permissionCheck;

    public ButtonPermissionAop(UserStore userStore, PermissionCheck permissionCheck) {
        this.userStore = userStore;
        this.permissionCheck = permissionCheck;
    }

    @Override
    public Pointcut getPointcut() {
        return new Pointcut() {
            @Override
            public ClassFilter getClassFilter() {
                return clazz -> clazz.getDeclaredAnnotation(Controller.class) != null || clazz.getDeclaredAnnotation(RestController.class) != null;
            }

            @Override
            public MethodMatcher getMethodMatcher() {
                return new AnnotationMethodMatcher(ButtonPermission.class);
            }
        };
    }

    @Override
    public Advice getAdvice() {
        return (MethodBeforeAdvice) (method, args, target) -> {
            ButtonPermission buttonPermission = method.getDeclaredAnnotation(ButtonPermission.class);
            String menuCode = buttonPermission.menuCode();
            String buttonCode = buttonPermission.buttonCode();
            BigInteger userId = userStore.getCurrentUser().getId();
            boolean check = permissionCheck.checkButtonPermission(userId, menuCode, buttonCode);
            if (!check) {
                throw new BusinessException(String.format("用户%s没有按钮%s的权限", userId, buttonCode));
            }
        };
    }

    @Override
    public boolean isPerInstance() {
        return true;
    }
}
